package com.ideal.hadoopadmin.api.hive;

import com.ideal.hadoopadmin.api.hdfs.HDFSAPI;
import com.ideal.hadoopadmin.api.linux.UserAPI;
import com.ideal.hadoopadmin.crontab.hive.FlushHiveInfo;
import com.ideal.service.hdfs.HDFSService;
import com.ideal.service.hive.HiveService;
import com.ideal.tools.ssh.common.CommonProperties;
import com.ideal.tools.ssh.common.CommonTools;
import com.ideal.tools.ssh.common.OperationMarket;
import com.ideal.tools.ssh.context.ClusterContext;
import com.ideal.tools.ssh.entity.LinuxMachine;

import java.util.List;

/**
 * Created by CC on 2016/3/15.
 */
public class HiveAPI {

    public static String HIVE_TABLE_NAME = "HIVE_TABLE_NAME";
    public static String HIVE_PRIVILE_USER = "HIVE_PRIVILE_USER";
    public static String HIVE_PRIVILE_TYPE = "HIVE_PRIVILE_TYPE";

    /**
     * machineList 需要放入hive namenode  机器
     * HDFS_PUB_TABLE_DIR 用户地址
     * Cluster_User_Name 地址所对应的表名
     * HIVE_TABLE_NAME hive 表名
     * HIVE_PRIVILE_USER
     *
     * @param context
     */
    public static void grantHivePrivilege(ClusterContext context){
        List<LinuxMachine> machineList = context.getOriginalList();
        CommonProperties commonProperties =context.getCommonProperties();

        //hdfs实体地址的后面
        String tblDIR = commonProperties.getArgument(HDFSAPI.HDFS_PUB_TABLE_DIR,"");//hive表地址
        String userName = commonProperties.getArgument(UserAPI.Cluster_User_Name,"");//地址所属用户
        String tableName = commonProperties.getArgument(HiveAPI.HIVE_TABLE_NAME,""); //表名
        String needPrivileUser = commonProperties.getArgument(HiveAPI.HIVE_PRIVILE_USER,"");//需要赋权的用户
        String PrivileType = commonProperties.getArgument(HiveAPI.HIVE_PRIVILE_TYPE,"select");

        String userGroup = CommonTools.getUserGroupByUser(userName, commonProperties);
        String tblGroup = CommonTools.getHDFSPubDirGroup(userName,tblDIR);
        String db_role  = CommonTools.getHiveRole("tb",PrivileType,userName+"_"+tblDIR,context.getCommonProperties());

        //用户需要加入两个组 首先是 user_group 这样才能访问父目录 ，tableGroup 访问本目录
        String groups=userGroup+","+tblGroup;

        List<LinuxMachine> finalmachines = CommonTools.megerMachineOperation(machineList,context);

        for(LinuxMachine machine: finalmachines) {
            for (LinuxMachine.MachineType machineType : machine.getMachineRoleTypes()) {
                if (machineType == LinuxMachine.MachineType.NameNode) {
                    //hive 这边赋权首先需要有hdfs 组权限
                    machine.initOperation(OperationMarket.JoinUserToGroup(needPrivileUser, groups));
                } else if (machineType == LinuxMachine.MachineType.Hive) {
                    //赋权角色
                    machine.initOperation(OperationMarket.GrantSentryPrivile(userName, tableName, needPrivileUser, db_role));
                }
            }
        }

        //重新设置 机器列表
        context.setMachineList(finalmachines);
        //执行
        context.doTheThing();
    }


    /**
     * machineList 需要放入hive namenode  机器
     * HDFS_PUB_TABLE_DIR 用户地址
     * Cluster_User_Name 地址所对应的表名
     * HIVE_TABLE_NAME hive 表名
     * HIVE_PRIVILE_USER
     *
     * @param context
     */
    public static void revokeHivePrivilege(ClusterContext context){
        List<LinuxMachine> machineList = context.getOriginalList();
        CommonProperties commonProperties =context.getCommonProperties();

        //hdfs实体地址的后面
        String tblDIR = commonProperties.getArgument(HDFSAPI.HDFS_PUB_TABLE_DIR,"");//hive表地址
        String userName = commonProperties.getArgument(UserAPI.Cluster_User_Name,"");//地址所属用户
        String tableName = commonProperties.getArgument(HiveAPI.HIVE_TABLE_NAME,""); //表名
        String needPrivileUser = commonProperties.getArgument(HiveAPI.HIVE_PRIVILE_USER,"");//需要赋权的用户
        String privileType = commonProperties.getArgument(HiveAPI.HIVE_PRIVILE_TYPE,"select");

        String userGroup = CommonTools.getUserGroupByUser(userName, commonProperties);
        String tblGroup = CommonTools.getHDFSPubDirGroup(userName,tblDIR);
        String db_role  = CommonTools.getHiveRole("tb",privileType,userName+"_"+tblDIR,context.getCommonProperties());

        String hasOtherAccess = commonProperties.getArgument(HDFSAPI.HDFS_HAS_OTHER_ACCESS, HDFSAPI.HDFS_TRUE);


        //用户需要加入两个组 首先是 user_group 这样才能访问父目录 ，tableGroup 访问本目录
        List<LinuxMachine> finalmachines = CommonTools.megerMachineOperation(machineList,context);

        for(LinuxMachine machine: finalmachines){
            for (LinuxMachine.MachineType machineType : machine.getMachineRoleTypes()) {
                if (machineType == LinuxMachine.MachineType.NameNode) {
                    //hive 这边赋权需要移除hdfs 组权限
                    machine.initOperation(OperationMarket.RemoveUserFromGroup(needPrivileUser, tblGroup));
                    //当不包含其他的时候 我们需要把 上级组也删除掉
                    if(hasOtherAccess.equals(HDFSAPI.HDFS_FALSE)){
                        machine.initOperation(OperationMarket.RemoveUserFromGroup(userName, userGroup));
                    }
                } else if (machineType == LinuxMachine.MachineType.Hive) {
                    //赋权角色
                    machine.initOperation(OperationMarket.RevokeSentryPrivile(userName, tableName, needPrivileUser, db_role));
                }
            }
        }

        //重新设置 机器列表
        context.setMachineList(finalmachines);
        //执行
        context.doTheThing();
    }

    /**
     * 首页 ->元数据管理 hive元数据管理 刷新列表
     * 1、刷新meta_hive_info
     * 2、刷新hdfs
     */
    public  static  void flushHiveInfo(ClusterContext context){
        new HDFSAPI().callFlushHdfsInfoBak(context);
        new FlushHiveInfo().initHiveMetadataNew(context);
    }

    /**
     *首页 ->元数据管理  hive元数据管理 查看按钮  sql建表语句
     * 根据meta_hive_info的id更新或增加meta_hive_sql的hiveSql
     * @param id
     */
    public  static  void flushHiveInfo_sql(Long id){
        new HiveService().handleHiveSql(id);
    }

    /**
     * 刷新hive信息（新方法）
     */
    public  static  void flushHive(ClusterContext context){
        new HiveService().refreshHive(context);
    }
}
